<template>
  <div
    style="width: 100%; height: 100%; overflow-y: auto; overflow-x: hidden; position: relative"
    @dragover="handleDragover"
    @drop="handleDrop"
  >
    <!--辅助线X-->
    <div
      v-if="container.auxiliaryLine.isOpen && container.auxiliaryLine.isShowXLine"
      :style="{ top: auxiliaryLinePos.y + 'px' }"
      class="auxiliary-line-x"
    />
    <!--辅助线Y-->
    <div
      v-if="container.auxiliaryLine.isOpen && container.auxiliaryLine.isShowYLine"
      :style="{ left: auxiliaryLinePos.x + 'px' }"
      class="auxiliary-line-y"
    />
    <div
      id="flowContainer"
      :class="{
        grid: flowData.config.showGrid,
        canDrag: container.dragFlag,
        canMultiple: rectangleMultiple.flag,
      }"
      :style="gridStyle"
      class="flow-container"
      @click.stop="containerHandler"
      @mousedown="mousedownHandler"
      @mousemove="mousemoveHandler"
      @mouseup="mouseupHandler"
      @mousewheel="scaleContainer"
      @DOMMouseScroll="scaleContainer"
      @contextmenu="showContainerContextMenu"
    >
      <flow-node
        v-for="node in flowData.nodeList"
        :key="node.id"
        :node="node"
        :flow-config="flowConfig"
        :plumb="plumb"
        :select.sync="currentSelect"
        :select-group.sync="currentSelectGroup"
        :current-tool="currentTool"
        :dragable="false"
        @showNodeContextMenu="showNodeContextMenu"
        @isMultiple="isMultiple"
        @updateNodePos="updateNodePos"
        @alignForLine="alignForLine"
        @hideAlignLine="hideAlignLine"
        @onResize="onResize"
        @nodeInfo="nodeInfo"
        @leftClickNode="leftClickNode"
      />

      <div v-show="existingDot" id="a-item_left" :style="{ top: spotTop, left: spotLeft }" class="item" />
      <div v-show="existingDot" id="a-item_right" :style="{ top: targetTop, left: targetLeft }" class="item" />

      <div
        v-if="rectangleMultiple.flag && rectangleMultiple.multipling"
        :style="{
          top: rectangleMultiple.position.top + 'px',
          left: rectangleMultiple.position.left + 'px',
          width: rectangleMultiple.width + 'px',
          height: rectangleMultiple.height + 'px',
        }"
        class="rectangle-multiple"
      />
    </div>
    <div class="container-scale">
      <a-button icon="zoom-out" size="small" type="default" @click="narrowContainer" />
      <span>{{ container.scaleShow }}%</span>
      <a-button icon="zoom-in" size="small" type="default" @click="enlargeContainer" />
    </div>
    <!-- <div class="mouse-position">
      x: {{ mouse.position.x }}, y: {{ mouse.position.y }}
    </div>-->
    <vue-context-menu
      :context-menu-data="containerContextMenuData"
      @flowInfo="flowInfo"
      @paste="paste"
      @selectAll="selectAll"
      @saveFlow="saveFlow"
      @verticaLeft="verticaLeft"
      @verticalCenter="verticalCenter"
      @verticalRight="verticalRight"
      @levelUp="levelUp"
      @levelCenter="levelCenter"
      @levelDown="levelDown"
      @addRemark="addRemark"
    />
    <vue-context-menu
      v-if="!portIndex"
      :context-menu-data="nodeContextMenuData"
      @copyNode="copyNode"
      @portNode="portNode"
      @deleteNode="deleteNode"
      @deletfffeNode="deletfffeNode"
      @handleNodeStart="handleNodeStart"
      @handleNodeStop="handleNodeStop"
      @handleNodeServer="handleNodeServer"
      @handleNodeInfo="handleNodeInfo"
    />
    <a-modal v-if="visible" v-model="visible" title="相关配置" width="65%" okText cancel-text="关闭" @cancel="handleOk">
      <!-- <div class="modal-box" v-if="visible">
        <xterm v-if="visible" :nodeId="nodeId" />
      </div>-->
      <a-tabs v-model="activeKey">
        <a-tab-pane key="1" tab="工作参数" :disabled="!deviceDatabase.deviceId">
          <!-- <a-descriptions title="状态信息" :column="2">
            <a-descriptions-item label="在网状态">在网</a-descriptions-item>
            <a-descriptions-item label="Telephone">18100</a-descriptions-item>
            <a-descriptions-item label="Live">Hangzhou</a-descriptions-item>
            <a-descriptions-item label="Remark">empty</a-descriptions-item>
          </a-descriptions> -->
          <gridConfig
            :deviceData="deviceDatabase"
            v-if="activeKey === '1'"
            :prohibit="true"
            :nodeData="rightNode"
            :sctiveType="rightNode.type"
          />
        </a-tab-pane>
        <a-tab-pane key="2" tab="配置" :disabled="!deviceDatabase.deviceId || isCommone">
          <gridConfig
            :deviceData="deviceDatabase"
            v-if="activeKey === '2'"
            :nodeData="rightNode"
            :prohibit="false"
            :sctiveType="rightNode.type"
          />
        </a-tab-pane>
        <a-tab-pane key="3" tab="网络" v-if="false">
          <a-form-model :model="form" :label-col="labelCol" :wrapper-col="wrapperCol">
            <a-form-model-item label="Ip地址">
              <a-input v-model="form.ip" />
            </a-form-model-item>
            <a-form-model-item label="端口号">
              <a-input v-model="form.port" />
              <!-- <a-select
                v-model="form.region"
                placeholder="please select your zone"
              >
                <a-select-option value="shanghai"> Zone one </a-select-option>
                <a-select-option value="beijing"> Zone two </a-select-option>
              </a-select>-->
            </a-form-model-item>

            <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
              <a-button type="primary" @click="onSubmit">应用</a-button>
              <!-- <a-button style="margin-left: 10px"> Cancel </a-button> -->
            </a-form-model-item>
          </a-form-model>
        </a-tab-pane>
        <a-tab-pane key="0" tab="设备信息">
          <a-form-model
            v-if="activeKey === '0'"
            :model="deviceData"
            :label-col="labelCol"
            :wrapper-col="wrapperCol"
            :rules="rules"
            ref="form"
          >
            <a-form-model-item label="设备id" prop="deviceId">
              <a-input v-model="deviceData.deviceId" />
            </a-form-model-item>
            <a-form-model-item label="设备名称" prop="name">
              <a-input v-model="deviceData.name" />
            </a-form-model-item>
            <a-form-model-item label="设备类型">
              <a-input v-model="deviceData.type" readonly />
            </a-form-model-item>
            <a-row >
              <a-form-model-item label="设备ip" prop="ip">
                <a-input v-model="deviceData.ip" />
              </a-form-model-item>
              <a-form-model-item label="设备端口" prop="port">
                <a-input v-model="deviceData.port" />
              </a-form-model-item>
            </a-row>
             <!-- <a-row v-if="!isFeedBaseband">
              <a-form-model-item label="设备ip" prop="ip">
                <a-input v-model="deviceData.ip" />
              </a-form-model-item>
              <a-form-model-item label="设备端口" prop="port">
                <a-input v-model="deviceData.port" />
              </a-form-model-item>
            </a-row>
           <a-row v-if="isFeedBaseband">
                 <a-form-model-item label="ip" prop="ip">
                <a-input v-model="deviceData.ip" />
              </a-form-model-item>
              <a-form-model-item label="端口" prop="port">
                <a-input v-model="deviceData.port" />
              </a-form-model-item>
              <a-form-model-item label="槽1ip" prop="ip1">
                <a-input v-model="deviceData.ip1" />
              </a-form-model-item>
              <a-form-model-item label="槽1端口" prop="port1">
                <a-input v-model="deviceData.port1" />
              </a-form-model-item>
              <a-form-model-item label="槽2ip" prop="ip2">
                <a-input v-model="deviceData.ip2" />
              </a-form-model-item>
              <a-form-model-item label="槽2端口" prop="port2">
                <a-input v-model="deviceData.port2" />
              </a-form-model-item>
              <a-form-model-item label="槽3ip" prop="ip3">
                <a-input v-model="deviceData.ip3" />
              </a-form-model-item>
              <a-form-model-item label="槽3端口" prop="port3">
                <a-input v-model="deviceData.port3" />
              </a-form-model-item>
              <a-form-model-item label="槽4ip" prop="ip4">
                <a-input v-model="deviceData.ip4" />
              </a-form-model-item>
              <a-form-model-item label="槽4端口" prop="port4">
                <a-input v-model="deviceData.port4" />
              </a-form-model-item>
            </a-row> -->

            <a-form-model-item label="本机端口" prop="localPort">
              <a-input v-model="deviceData.localPort" />
            </a-form-model-item>
            <a-form-model-item label="设备生产商">
              <a-input v-model="deviceData.manufacturer" />
            </a-form-model-item>
            <a-form-model-item label="所属单位">
              <a-input v-model="deviceData.departments" />
            </a-form-model-item>
            <a-form-model-item label="位置信息">
              <a-input v-model="deviceData.position" />
            </a-form-model-item>

            <a-form-model-item :wrapper-col="{ span: 10, offset: 11 }">
              <a-button type="primary" @click="handleNodeEscalation" style="margin-right: 10px">设备信息上报</a-button>
              <a-button type="primary" @click="addDeviceData">保存配置</a-button>
              <!-- <a-button style="margin-left: 10px"> Cancel </a-button> -->
            </a-form-model-item>
          </a-form-model>
        </a-tab-pane>
      </a-tabs>
      <template slot="footer">
        <a-button @click="handleOk">关闭</a-button>
      </template>
    </a-modal>
    <server-modal ref="serverModalForm" @ok="serverModalFormOk"></server-modal>
  </div>
</template>

<script>
import ServerModal from './ServerModal'
import { utils } from '../utils/common.js'
import FlowNode from './FlowNode'
import { containerMenu, linkNodeMenu, nodeMenu1 } from '../config/contextMenu.js'
import { flowStatus } from '../config/flow.js'
import xterm from '@/components/xterm/index'
import { httpAction, getAction } from '@api/manage'
import gridConfig from './grifConfig.vue'
import { Modal } from 'ant-design-vue'
export default {
  components: { gridConfig, ServerModal, FlowNode, xterm },
  // eslint-disable-next-line vue/require-prop-types
  props: [
    'browserType',
    'flowData',
    'plumb',
    'select',
    'selectGroup',
    'currentTool',
    'dragInfo',
    'flowConfig',
    'portIndex',
  ],
  data() {
    return {
      nodeId: '',
      currentNode: {},
      url: {
        start: '/kafka/send-start',
        stop: '/kafka/send-stop',
        add: '/device/dmDevice/add',
        edit: '/device/dmDevice/edit',
      },
      activeKey: '0',
      context: 'redis:0',
      visible: false,
      spotTop: '0px',
      spotLeft: '0px',
      targetTop: '0px',
      targetLeft: '0px',
      tempNode: {},
      rightNode: {},
      deviceData: {},
      deviceDatabase: {},
      existingDot: false,
      currentSelect: this.select,
      currentSelectGroup: this.selectGroup,
      container: {
        pos: {
          top: -4000,
          left: -4000,
        },
        dragFlag: false,
        draging: false,
        scale: this.flowConfig.defaultStyle.containerScale.init,
        scaleFlag: false,
        scaleOrigin: {
          x: 0,
          y: 0,
        },
        scaleShow: utils.mul(this.flowConfig.defaultStyle.containerScale.init, 80),
        // 辅助线
        auxiliaryLine: {
          isOpen: this.flowConfig.defaultStyle.isOpenAuxiliaryLine,
          isShowXLine: false,
          isShowYLine: false,
          controlFnTimesFlag: true,
        },
      },
      // 辅助线位置
      auxiliaryLinePos: {
        x: 0,
        y: 0,
      },
      mouse: {
        position: {
          x: 0,
          y: 0,
        },
        // 鼠标点击起始位置
        tempPos: {
          x: 0,
          y: 0,
        },
      },
      // 鼠标划框多选
      rectangleMultiple: {
        flag: false, // 是否按了ctrl键
        multipling: false,
        position: {
          top: 0,
          left: 0,
        },
        height: 0,
        width: 0,
      },
      containerContextMenuData: !this.portIndex ? containerMenu : {},
      nodeContextMenuData: !this.portIndex ? nodeMenu1 : {},
      // 当前聚焦的连接线ID
      tempLinkId: '',
      // 剪切板内容
      clipboard: [],
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      form: {},
      rules: {
        name: [{ required: true, message: '请输入设备名称' }],
        ip: [{ required: true, message: '请输入设备ip' }],
        port: [{ required: true, message: '请输入设备端口' }],
        ip1: [{ required: true, message: '请输入槽口1ip' }],
        port1: [{ required: true, message: '请输入槽口1端口' }],
        ip2: [{ required: true, message: '请输入槽口2ip' }],
        port2: [{ required: true, message: '请输入槽口2端口' }],
        ip3: [{ required: true, message: '请输入槽口3ip' }],
        port3: [{ required: true, message: '请输入槽口3端口' }],
        ip4: [{ required: true, message: '请输入槽口4ip' }],
        port4: [{ required: true, message: '请输入槽口4端口' }],
        localPort: [{ required: true, message: '请输入本机端口' }],
        deviceId: [{ required: true, message: '请输入设备id' }],
      },
      timer: null,
      isFeedBaseband: false,
      isCommone: false,
    }
  },
  computed: {
    gridStyle() {
      return {
        top: `${this.container.pos.top}px`,
        left: `${this.container.pos.left}px`,
        transform: `scale(${this.container.scale})`,
        transformOrigin: `${this.container.scaleOrigin.x}px ${this.container.scaleOrigin.y}px`,
      }
    },
  },
  watch: {
    flowData: {
      handler(valNew, valOld) {},
      deep: true,
    },
    visible(valNew) {
      if (valNew) {
        // this.timer = setInterval(()=>{
        if (this.activeKey === '0') {
          // this.getDeviceData()
        } else {
          clearInterval(this.timer)
        }
        // },0)
      } else {
        clearInterval(this.timer)
      }
    },
    activeKey(valNew) {
      if (valNew === '0') {
        if (this.visible) {
          // this.timer = setInterval(()=> {
          // this.getDeviceData()
          // },0)
        } else {
          clearInterval(this.timer)
        }
      }
    },
    select(val) {
      this.currentSelect = val
      // 清除连接线焦点
      if (this.tempLinkId !== '') {
        document.querySelector('#' + this.tempLinkId) &&
          document.querySelector('#' + this.tempLinkId).classList.remove('link-active')
        this.tempLinkId = ''
      }
      // 设置连接线焦点
      if (this.currentSelect.type === 'link') {
        this.tempLinkId = this.currentSelect.id
        document.querySelector('#' + this.currentSelect.id) &&
          document.querySelector('#' + this.currentSelect.id).classList.add('link-active')
      }
    },
    currentSelect: {
      handler(val) {
        this.$emit('update:select', val)
      },
      deep: true,
    },
    selectGroup(val) {
      this.currentSelectGroup = val
      if (this.currentSelectGroup.length <= 0) this.plumb.clearDragSelection()
    },
    currentSelectGroup: {
      handler(val) {
        this.$emit('update:selectGroup', val)
      },
      deep: true,
    },
  },
  methods: {
    setData(node) {
      // 保存选中拓扑的数据
      this.currentNode = node
    },
    getDeviceData() {
      getAction('/device/dmDevice/getByTopologyInstId', { topologyInstId: this.currentNode.id }).then((res) => {
        if (res.success) {
          this.deviceDatabase = res.result || {}
          this.deviceData = res.result || {}
          //馈电基带
          if (res.result && res.result.topologyInstId && res.result.topologyInstId.includes('feedBaseband')) {
            this.isFeedBaseband = true
          } else {
            this.isFeedBaseband = false
          }
          //是载荷
          if (res.result && res.result.topologyInstId && res.result.topologyInstId.includes('commone')) {
            this.isCommone = true
          } else {
            this.isCommone = false
          }
        } else {
          this.$message.error(res.message)
        }
      })
    },
    handleNodeEscalation() {
      const tempData = {
        datas: [
          {
            name: this.deviceDatabase.name,
            deviceId: this.deviceDatabase.deviceId,
            type: this.deviceDatabase.type,
            ip: this.deviceDatabase.ip,
            port: this.deviceDatabase.port, // 端口
            departments: this.deviceDatabase.departments,
            position: this.deviceDatabase.position,
            manufacturer: this.deviceDatabase.manufacturer,
            swVer: '',
            status: '',
            remark: '',
          },
        ],
      }
      httpAction('/scriptUdp/udp/deviceInfoReport', tempData, 'post').then((res) => {
        if (res.success) {
          // this.getDeviceData()
          this.$message.success(res.message)
        } else {
          this.$message.error(res.message)
        }
      })
    },
    addDeviceData() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.deviceData.topologyInstId = this.currentNode.id
          // 通过查询到的值判断为新增还是编辑
          httpAction(this.deviceDatabase.deviceId ? this.url.edit : this.url.add, this.deviceData, 'post').then(
            (res) => {
              if (res.success) {
                // this.getDeviceData()
                this.$message.success(res.message)
              } else {
                this.$message.error(res.message)
              }
            }
          )
        }
      })
    },
    onSubmit() {
      console.log('submit!', this.form)
    },
    callback(val) {
      console.log(val)
    },
    nodeInfo(node) {
      console.log(node)
      this.$emit('nodeInfo', node)
    },
    serverModalFormOk() {},
    handleDragover(e) {
      e.preventDefault()
      this.mousemoveHandler(e)
    },
    handleDrop() {
      const belongTo = this.dragInfo.belongTo
      const type = this.dragInfo.type
      // 复位拖拽工具
      this.$emit('selectTool', 'drag')
      this.$emit('findNodeConfig', belongTo, type, (node) => {
        console.log(node)
        if (!node) {
          this.$message.error('未知的节点类型！')
          return
        }
        // 增加节点
        this.addNewNode(node)
      })
    },
    // 画布鼠标按下
    mousedownHandler(e) {
      const event = window.event || e

      if (event.button === 0) {
        if (this.container.dragFlag) {
          this.mouse.tempPos = this.mouse.position
          this.container.draging = true
        }

        this.currentSelectGroup = []
        if (this.rectangleMultiple.flag) {
          this.mouse.tempPos = this.mouse.position
          this.rectangleMultiple.multipling = true
        }
      }
    },
    // 画布鼠标移动
    mousemoveHandler(e) {
      const event = window.event || e

      if (event.target.id === 'flowContainer') {
        this.mouse.position = {
          x: event.offsetX,
          y: event.offsetY,
        }
      } else {
        const cn = event.target.className
        const tn = event.target.tagName
        if (cn !== 'lane-text' && cn !== 'lane-text-div' && tn !== 'svg' && tn !== 'path' && tn !== 'I') {
          this.mouse.position.x = event.target.offsetLeft + event.offsetX
          this.mouse.position.y = event.target.offsetTop + event.offsetY
        }
      }
      if (this.container.draging) {
        let nTop = this.container.pos.top + (this.mouse.position.y - this.mouse.tempPos.y)
        let nLeft = this.container.pos.left + (this.mouse.position.x - this.mouse.tempPos.x)
        if (nTop >= 0) nTop = 0
        if (nLeft >= 0) nLeft = 0
        this.container.pos = {
          top: nTop,
          left: nLeft,
        }
      }
      if (this.rectangleMultiple.multipling) {
        let h = this.mouse.position.y - this.mouse.tempPos.y
        let w = this.mouse.position.x - this.mouse.tempPos.x
        let t = this.mouse.tempPos.y
        let l = this.mouse.tempPos.x
        if (h >= 0 && w < 0) {
          w = -w
          l -= w
        } else if (h < 0 && w >= 0) {
          h = -h
          t -= h
        } else if (h < 0 && w < 0) {
          h = -h
          w = -w
          t -= h
          l -= w
        }
        this.rectangleMultiple.height = h
        this.rectangleMultiple.width = w
        this.rectangleMultiple.position.top = t
        this.rectangleMultiple.position.left = l
      }

      // 已选择端点后的点,实时更新线
      // if(this.existingDot){
      //   this.targetTop = this.mouse.position.y + 'px'
      //   this.targetLeft = this.mouse.position.x + 'px'
      //   // this.$nextTick(()=>{
      //     this.plumb.addEndpoint('a-item_left', {
      //       anchors: ['Center'],
      //       uuid: 'werLeftIdB',
      //     })
      //     this.plumb.addEndpoint('a-item_right', {
      //       anchors: ['Center'],
      //       uuid: 'werRightIdA',
      //     })
      //     this.plumb.connect({ uuids: ['werLeftIdB', 'werRightIdA'] })
      //   // })

      // }
    },
    // 画布鼠标点击松开
    mouseupHandler() {
      if (this.container.draging) this.container.draging = false
      if (this.rectangleMultiple.multipling) {
        // 鼠标划框内的节点
        this.judgeSelectedNode()
        this.rectangleMultiple.multipling = false
        this.rectangleMultiple.width = 0
        this.rectangleMultiple.height = 0
      }
    },
    // 鼠标划框内的节点
    judgeSelectedNode() {
      const ay = this.rectangleMultiple.position.top
      const ax = this.rectangleMultiple.position.left
      const by = ay + this.rectangleMultiple.height
      const bx = ax + this.rectangleMultiple.width

      const nodeList = this.flowData.nodeList
      nodeList.forEach((node) => {
        if (node.y >= ay && node.x >= ax && node.y <= by && node.x <= bx) {
          this.plumb.addToDragSelection(node.id)
          this.currentSelectGroup.push(node)
        }
      })
    },
    // 画布鼠标滚轴
    scaleContainer(e) {
      const event = window.event || e

      if (this.container.scaleFlag) {
        if (this.browserType === 2) {
          if (event.detail < 0) {
            this.enlargeContainer()
          } else {
            this.narrowContainer()
          }
        } else {
          if (event.deltaY < 0) {
            this.enlargeContainer()
          } else if (this.container.scale) {
            this.narrowContainer()
          }
        }
      }
    },
    // 画布放大
    enlargeContainer() {
      this.container.scaleOrigin.x = this.mouse.position.x
      this.container.scaleOrigin.y = this.mouse.position.y
      const newScale = utils.add(this.container.scale, this.flowConfig.defaultStyle.containerScale.onceEnlarge)
      if (newScale <= this.flowConfig.defaultStyle.containerScale.max) {
        this.container.scale = newScale
        this.container.scaleShow = utils.mul(this.container.scale, 100)
        this.plumb.setZoom(this.container.scale)
      }
    },
    // 画布缩小
    narrowContainer() {
      this.container.scaleOrigin.x = this.mouse.position.x
      this.container.scaleOrigin.y = this.mouse.position.y
      const newScale = utils.sub(this.container.scale, this.flowConfig.defaultStyle.containerScale.onceNarrow)
      if (newScale >= this.flowConfig.defaultStyle.containerScale.min) {
        this.container.scale = newScale
        this.container.scaleShow = utils.mul(this.container.scale, 100)
        this.plumb.setZoom(this.container.scale)
      }
    },
    // 画布右健
    showContainerContextMenu(e) {
      const event = window.event || e

      event.preventDefault()
      document.querySelector('.vue-contextmenuName-node-menu').style.display = 'none'
      document.querySelector(
        !this.portIndex ? '.vue-contextmenuName-link-menu' : '.vue-contextmenuName-link-menus'
      ).style.display = 'none'

      this.selectContainer()
      const x = event.clientX + 100
      const y = event.clientY
      this.containerContextMenuData.axis = { x, y }
    },
    // 节点右键
    showNodeContextMenu(e, node) {
      this.nodeId = e.id
      this.tempNode = e
      this.rightNode = node //右键的设备
      this.setData(node)
      if (this.currentTool.type === 'connection') {
        this.nodeContextMenuData = linkNodeMenu
      } else {
        this.nodeContextMenuData = nodeMenu1
      }
      const event = window.event || e
      event.preventDefault()
      document.querySelector('.vue-contextmenuName-flow-menu').style.display = 'none'
      document.querySelector('.vue-contextmenuName-link-menu').style.display = 'none'
      const x = event.clientX
      const y = event.clientY
      this.nodeContextMenuData.axis = { x, y }
    },
    // 拓扑图信息
    flowInfo() {
      const nodeList = this.flowData.nodeList
      const linkList = this.flowData.linkList
      console.log(this.flowData.nodeList, this.flowData.linkList)
      this.$message.info('当前拓扑图中有 ' + nodeList.length + ' 个节点，有 ' + linkList.length + ' 条连线。')
    },
    // 粘贴
    paste() {
      let dis = 0
      this.clipboard.forEach((node) => {
        const newNode = Object.assign({}, node)
        newNode.id = newNode.type + '-' + utils.getId()
        const nodePos = this.computeNodePos(this.mouse.position.x + dis, this.mouse.position.y + dis)
        newNode.x = nodePos.x
        newNode.y = nodePos.y
        dis += 20
        this.flowData.nodeList.push(newNode)
      })
    },
    // 全选
    selectAll() {
      this.flowData.nodeList.forEach((node) => {
        this.plumb.addToDragSelection(node.id)
        this.currentSelectGroup.push(node)
      })
    },
    // 保存流程
    saveFlow() {
      this.$emit('saveFlow')
    },
    // 节点排列前校验节点数量
    checkAlign() {
      if (this.currentSelectGroup.length < 2) {
        this.$message.error('请选择至少两个节点！')
        return false
      }
      return true
    },
    // 垂直左对齐
    verticaLeft() {
      if (!this.checkAlign()) return
      const nodeList = this.flowData.nodeList
      const selectGroup = this.currentSelectGroup
      const baseX = selectGroup[0].x
      let baseY = selectGroup[0].y
      for (let i = 1; i < selectGroup.length; i++) {
        baseY = baseY + selectGroup[i - 1].height + this.flowConfig.defaultStyle.alignSpacing.vertical
        const f = nodeList.find((n) => n.id === selectGroup[i].id)
        f.tx = baseX
        f.ty = baseY
        this.plumb.animate(
          selectGroup[i].id,
          { top: baseY, left: baseX },
          {
            duration: this.flowConfig.defaultStyle.alignDuration,
            complete: function () {
              f.x = f.tx
              f.y = f.ty
            },
          }
        )
      }
    },
    // 垂直居中
    verticalCenter() {
      if (!this.checkAlign()) return
      const nodeList = this.flowData.nodeList
      const selectGroup = this.currentSelectGroup
      let baseX = selectGroup[0].x
      let baseY = selectGroup[0].y
      const firstX = baseX
      for (let i = 1; i < selectGroup.length; i++) {
        baseY = baseY + selectGroup[i - 1].height + this.flowConfig.defaultStyle.alignSpacing.vertical
        baseX = firstX + utils.div(selectGroup[0].width, 2) - utils.div(selectGroup[i].width, 2)
        const f = nodeList.find((n) => n.id === selectGroup[i].id)
        f.tx = baseX
        f.ty = baseY
        this.plumb.animate(
          selectGroup[i].id,
          { top: baseY, left: baseX },
          {
            duration: this.flowConfig.defaultStyle.alignDuration,
            complete: function () {
              f.x = f.tx
              f.y = f.ty
            },
          }
        )
      }
    },
    // 垂直右对齐
    verticalRight() {
      if (!this.checkAlign()) return
      const nodeList = this.flowData.nodeList
      const selectGroup = this.currentSelectGroup
      let baseX = selectGroup[0].x
      let baseY = selectGroup[0].y
      const firstX = baseX
      for (let i = 1; i < selectGroup.length; i++) {
        baseY = baseY + selectGroup[i - 1].height + this.flowConfig.defaultStyle.alignSpacing.vertical
        baseX = firstX + selectGroup[0].width - selectGroup[i].width
        const f = nodeList.find((n) => n.id === selectGroup[i].id)
        f.tx = baseX
        f.ty = baseY
        this.plumb.animate(
          selectGroup[i].id,
          { top: baseY, left: baseX },
          {
            duration: this.flowConfig.defaultStyle.alignDuration,
            complete: function () {
              f.x = f.tx
              f.y = f.ty
            },
          }
        )
      }
    },
    // 水平上对齐
    levelUp() {
      if (!this.checkAlign()) return
      const nodeList = this.flowData.nodeList
      const selectGroup = this.currentSelectGroup
      let baseX = selectGroup[0].x
      const baseY = selectGroup[0].y
      for (let i = 1; i < selectGroup.length; i++) {
        baseX = baseX + selectGroup[i - 1].width + this.flowConfig.defaultStyle.alignSpacing.horizontal
        const f = nodeList.find((n) => n.id === selectGroup[i].id)
        f.tx = baseX
        f.ty = baseY
        this.plumb.animate(
          selectGroup[i].id,
          { top: baseY, left: baseX },
          {
            duration: this.flowConfig.defaultStyle.alignDuration,
            complete: function () {
              f.x = f.tx
              f.y = f.ty
            },
          }
        )
      }
    },
    // 水平居中
    levelCenter() {
      if (!this.checkAlign()) return
      const nodeList = this.flowData.nodeList
      const selectGroup = this.currentSelectGroup
      let baseX = selectGroup[0].x
      let baseY = selectGroup[0].y
      const firstY = baseY
      for (let i = 1; i < selectGroup.length; i++) {
        baseY = firstY + utils.div(selectGroup[0].height, 2) - utils.div(selectGroup[i].height, 2)
        baseX = baseX + selectGroup[i - 1].width + this.flowConfig.defaultStyle.alignSpacing.horizontal
        const f = nodeList.find((n) => n.id === selectGroup[i].id)
        f.tx = baseX
        f.ty = baseY
        this.plumb.animate(
          selectGroup[i].id,
          { top: baseY, left: baseX },
          {
            duration: this.flowConfig.defaultStyle.alignDuration,
            complete: function () {
              f.x = f.tx
              f.y = f.ty
            },
          }
        )
      }
    },
    // 水平下对齐
    levelDown() {
      if (!this.checkAlign()) return
      const nodeList = this.flowData.nodeList
      const selectGroup = this.currentSelectGroup
      let baseX = selectGroup[0].x
      let baseY = selectGroup[0].y
      const firstY = baseY
      for (let i = 1; i < selectGroup.length; i++) {
        baseY = firstY + selectGroup[0].height - selectGroup[i].height
        baseX = baseX + selectGroup[i - 1].width + this.flowConfig.defaultStyle.alignSpacing.horizontal
        const f = nodeList.find((n) => n.id === selectGroup[i].id)
        f.tx = baseX
        f.ty = baseY
        this.plumb.animate(
          selectGroup[i].id,
          { top: baseY, left: baseX },
          {
            duration: this.flowConfig.defaultStyle.alignDuration,
            complete: function () {
              f.x = f.tx
              f.y = f.ty
            },
          }
        )
      }
    },
    addRemark() {
      this.$message.info('添加备注(待完善)...')
    },

    // 连线节点鼠标位置
    mousePosition(node) {
      let x = this.mouse.position.x
      let y = this.mouse.position.y
      const nodePos = this.computeNodePos(x, y)
      x = nodePos.x
      y = nodePos.y

      const newNode = Object.assign({}, node)
      newNode.id = newNode.type + '-' + utils.getId()
      newNode.height = 50
      if (
        newNode.type === 'start' ||
        newNode.type === 'end' ||
        newNode.type === 'event' ||
        newNode.type === 'gateway'
      ) {
        newNode.x = x - 25
        newNode.width = 50
      } else {
        newNode.x = x - 60
        newNode.width = 120
      }
      newNode.y = y - 25
      if (newNode.type === 'x-lane') {
        newNode.height = 200
        newNode.width = 500
      } else if (newNode.type === 'y-lane') {
        newNode.height = 500
        newNode.width = 200
      }
      return newNode
    },
    // 端口节点
    portNode() {
      // 显示点
      this.existingDot = true

      const nodePos = this.computeNodePos(this.mouse.position.x + 0, this.mouse.position.y + 0)
      this.spotTop = nodePos.y + 'px'
      this.spotLeft = nodePos.x + 'px'
    },
    // 复制节点
    copyNode() {
      this.clipboard = []
      if (this.currentSelectGroup.length > 0) {
        this.clipboard = Object.assign([], this.currentSelectGroup)
      } else if (this.currentSelect.id) {
        this.clipboard.push(this.currentSelect)
      }
    },
    leftClickNode(val) {
      console.log(val, '左键节点')
      this.$emit('leftClickSelectNode', val)
    },
    // 查询删除节点关联的连接线
    getConnectionsByNodeId(nodeId) {
      const conns1 = this.plumb.getConnections({
        source: nodeId,
      })
      const conns2 = this.plumb.getConnections({
        target: nodeId,
      })
      return conns1.concat(conns2)
    },
    onExecCmd(key, command, success, failed) {
      const allClass = ['success', 'error', 'system', 'info', 'warning']

      const clazz = allClass[Math.floor(Math.random() * allClass.length)]
      success({
        type: 'normal',
        class: clazz,
        tag: '成功',
        content: '123',
      })
    },
    handleOk(e) {
      this.visible = false
    },
    deletfffeNode() {
      this.$emit('nodeId', this.nodeId)
      // 清空上个设备的值
      this.deviceData = {}
      this.deviceDatabase = {}

      // 获取设备信息
      // this.getDeviceData()
      this.activeKey = '0'
      this.visible = true
    },
    handleNodeInfo() {
      this.$emit('openWin', 1)
    },
    handleNodeStart() {
      httpAction(this.url.start, {}, 'post')
        .then((res) => {
          if (res.success) {
            this.$emit('NodeStart', 1)
            this.$message.success('启动成功')
          } else {
            this.$message.warning(res.message)
          }
        })
        .finally(() => {})
    },
    handleNodeStop() {
      httpAction(this.url.stop, {}, 'post')
        .then((res) => {
          if (res.success) {
            this.$emit('NodeStart', 1)
            this.$message.success('停止成功')
          } else {
            this.$message.warning(res.message)
          }
        })
        .finally(() => {})
    },
    handleNodeServer() {
      this.$refs.serverModalForm.add()
      this.$refs.serverModalForm.title = '填写服务器'
      this.$refs.serverModalForm.disableSubmit = false
    },
    // 删除节点
    deleteNode() {
      Modal.confirm({
        title: '确认操作',
        content: '你确定要删除这个设备吗？',
        okText: '确认',
        cancelText: '取消',
        onOk: () => {
          // return new Promise((resolve, reject) => {
          // 这里可以添加你的确认操作逻辑
          this.$emit('deleteNode', this.currentSelect)
          const nodeList = this.flowData.nodeList
          const linkList = this.flowData.linkList
          const arr = []

          arr.push(Object.assign({}, this.currentSelect))

          this.flowData.status = flowStatus.LOADING

          arr.forEach((c) => {
            const conns = this.getConnectionsByNodeId(c.id)
            conns.forEach((conn) => {
              linkList.splice(
                linkList.findIndex((link) => link.sourceId === conn.sourceId && link.targetId === conn.targetId),
                1
              )
              this.plumb.deleteConnection(
                this.plumb.getConnections({
                  source: conn.sourceId,
                  target: conn.targetId,
                })[0]
              )
            })
            const inx = nodeList.findIndex((node) => node.id === c.id)
            nodeList.splice(inx, 1)
          })
          this.flowData.status = flowStatus.CREATE
          this.selectContainer()
          // }).catch(() => console.log('Oops errors!'))
        },
        onCancel() {
          console.log('取消删除')
        },
      })
    },
    // 增加画布节点
    addNewNode(node) {
      let x = this.mouse.position.x
      let y = this.mouse.position.y
      console.log(x, y)
      const nodePos = this.computeNodePos(x, y)
      x = nodePos.x
      y = nodePos.y

      const newNode = Object.assign({}, node)
      newNode.id = newNode.type + '-' + utils.getId()
      newNode.vmDeviceId = this.dragInfo.id
      newNode.height = 50
      if (
        newNode.type === 'start' ||
        newNode.type === 'end' ||
        newNode.type === 'event' ||
        newNode.type === 'gateway'
      ) {
        newNode.x = x - 25
        newNode.width = 50
      } else {
        newNode.x = x - 60
        newNode.width = 120
      }
      newNode.y = y - 25
      if (newNode.type === 'x-lane') {
        newNode.height = 200
        newNode.width = 500
      } else if (newNode.type === 'y-lane') {
        newNode.height = 500
        newNode.width = 200
      }

      this.flowData.nodeList.push(newNode)
      // 记录新增节点
      httpAction('/topologyInst/dmTopologyInst/add', newNode, 'post').then((res) => {
        // if (res.success) {
        //   this.$message.success('连线成功')
        // } else {
        //   this.$message.error(res.message)
        // }
      })
    },
    // x, y取整计算
    computeNodePos(x, y) {
      const pxx = this.flowConfig.defaultStyle.alignGridPX[0]
      const pxy = this.flowConfig.defaultStyle.alignGridPX[1]
      if (x % pxx) x = pxx - (x % pxx) + x
      if (y % pxy) y = pxy - (y % pxy) + y
      return {
        x: x,
        y: y,
      }
    },
    // 点击画布
    containerHandler() {
      this.selectContainer()
    },
    // 清除面布已选内容
    selectContainer() {
      this.currentSelect = {}
      // 开启快捷键
      this.$emit('getShortcut')
    },
    // 是否为多选行为
    isMultiple(callback) {
      callback(this.rectangleMultiple.flag)
    },
    // 更新组节点信息
    updateNodePos() {
      const nodeList = this.flowData.nodeList
      this.currentSelectGroup.forEach((node) => {
        const l = parseInt(document.querySelector('#' + node.id).style.left)
        const t = parseInt(document.querySelector('#' + node.id).style.top)
        const f = nodeList.find((n) => n.id === node.id)
        f.x = l
        f.y = t
      })
    },
    // 计算辅助线
    alignForLine(e) {
      if (this.selectGroup.length > 1) return
      if (this.container.auxiliaryLine.controlFnTimesFlag) {
        const elId = e.el.id
        const nodeList = this.flowData.nodeList
        nodeList.forEach((node) => {
          if (elId !== node.id) {
            const dis = this.flowConfig.defaultStyle.showAuxiliaryLineDistance
            const elPos = e.pos
            const elH = e.el.offsetHeight
            const elW = e.el.offsetWidth
            const disX = elPos[0] - node.x
            const disY = elPos[1] - node.y

            if ((disX >= -dis && disX <= dis) || (disX + elW >= -dis && disX + elW <= dis)) {
              this.container.auxiliaryLine.isShowYLine = true
              this.auxiliaryLinePos.x = node.x + this.container.pos.left
              const nodeMidPointX = node.x + node.width / 2
              if (nodeMidPointX === elPos[0] + elW / 2) {
                this.auxiliaryLinePos.x = nodeMidPointX + this.container.pos.left
              }
            }
            if ((disY >= -dis && disY <= dis) || (disY + elH >= -dis && disY + elH <= dis)) {
              this.container.auxiliaryLine.isShowXLine = true
              this.auxiliaryLinePos.y = node.y + this.container.pos.top
              const nodeMidPointY = node.y + node.height / 2
              if (nodeMidPointY === elPos[1] + elH / 2) {
                this.auxiliaryLinePos.y = nodeMidPointY + this.container.pos.left
              }
            }
          }
        })
        this.container.auxiliaryLine.controlFnTimesFlag = false
        setTimeout(() => {
          this.container.auxiliaryLine.controlFnTimesFlag = true
        }, 200)
      }
    },
    onResize() {
      this.plumb.repaintEverything()
    },
    // 隐藏辅助线
    hideAlignLine() {
      if (this.container.auxiliaryLine.isOpen) {
        this.container.auxiliaryLine.isShowXLine = false
        this.container.auxiliaryLine.isShowYLine = false
      }
    },
  },
}
</script>
<style lang="less" scoped>
.modal-box {
  width: 100%;
  height: 100%;
}
.item {
  height: 8px;
  width: 8px;
  border: 0px solid #2a2929;
  border-radius: 50%;
  background-color: #2a2929;
  position: absolute;
  transition-property: all;
}
::v-deep .ant-modal {
  padding-bottom: 0;
}
</style>
